package net.sevear.chaos.recommend
{
	import com.adobe.serialization.json.JSON;
	import com.douban.auth.DBAuthenticate;
	
	import de.popforge.utils.SprintfUtil;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	
	import mx.collections.ArrayCollection;
	import mx.formatters.DateFormatter;
	
	import net.sevear.chaos.download.Predef;
	import net.sevear.chaos.event.ChaosErrorEvent;
	import net.sevear.chaos.event.ContactEvent;
	import net.sevear.chaos.utils.Logger;
	import net.sevear.chaos.view.ChaosLogPanel;
	import net.sevear.chaos.vo.ChaosErrMsgConfig;
	import net.sevear.chaos.vo.UserInfo;
	
	public class ContactManager extends EventDispatcher
	{
		
		public static const MAX:int = 6;
		
		private static const CONTACT_URL:String = "/c/";
		
		private static const SEARCH_MY_INFO:int 		= 1;
		private static const SEARCH_USER_INFO:int 		= 2;
		private static const SEARCH_DB_USER_INFO:int 	= 3;
		
		private var op:int;
		private var loader:URLLoader;
		private var _list:ArrayCollection;
		private var isSendingRequest:Boolean = false;
		
		private var remoteRst:ChaosRemoteRequest;
		
		private var _searchUID:int;
		public function ContactManager(target:IEventDispatcher=null)
		{
			super(target);
			
			_list = new ArrayCollection();
			if(loader==null){
				loader = new URLLoader();
				loader.addEventListener(Event.COMPLETE,onLoadComplete);
				loader.addEventListener(IOErrorEvent.IO_ERROR,onIOError);
			}
			
			remoteRst = new ChaosRemoteRequest(0);
			remoteRst.addEventListener(ChaosErrorEvent.CHAOS_ERR,onChaosErr);
		}
		
		private static var _instance:ContactManager;
		public static function getInstance():ContactManager{
			if(_instance==null){
				_instance = new ContactManager();
			}
			
			return _instance;
		}
		
		public function get contacts():ArrayCollection{
			return _list;
		}
		
		public function updateContactList(uid:int):void{
			var rst:URLRequest = new URLRequest(encodeURI(Predef.CHAOS_HOST+CONTACT_URL));
			var vars:URLVariables = new URLVariables();
			vars.uid = uid;
			rst.data = vars;
			rst.method = URLRequestMethod.GET;
			remoteRst.sendRequest(rst,onGetContactList);
		}
		
		public function getLatestLikeRecommends(uids:Array):void{
			var rst:URLRequest = new URLRequest(encodeURI(Predef.CHAOS_HOST+CONTACT_URL));
			var vars:URLVariables = new URLVariables();
			vars.uids = uids;
			vars.op = "l";
			rst.data = vars;
			rst.method = URLRequestMethod.GET;
			remoteRst.sendRequest(rst,onGetLatestLikeRecommends);
		}
		
		public function searchMyInfo(email:String):void{
			if(isSendingRequest==false){
				var rst:URLRequest = new URLRequest();
				rst.url = SprintfUtil.sprintf("http://api.douban.com/people?q=%s&start-index=%d&max-results=%d&apikey=%s",
					encodeURI(email),0,10,Predef.API_KEY);
				rst.method = URLRequestMethod.GET;
				isSendingRequest = true;
				op = SEARCH_MY_INFO;
				loader.load(rst);
			}
		}
		
		public function searchDBUserInfo(uid:int):void{
			if(isSendingRequest==false){
				_searchUID = uid;
				var rst:URLRequest = new URLRequest();
				rst.url = SprintfUtil.sprintf("http://shuo.douban.com/api/users/%d",uid);
				rst.method = URLRequestMethod.GET;
				isSendingRequest = true;
				op = SEARCH_DB_USER_INFO;
				loader.load(rst);
			}
		}
		
		private function onGetContactList(rstStr:String):void{
			var jsonObj:Object = JSON.decode(rstStr);
			parseContactList(jsonObj as Array);
			dispatchEvent(new ContactEvent(ContactEvent.GET_NEW_LIST));
		}
		
		private function onGetLatestLikeRecommends(rstStr:String):void{
			
		}
		
		private var _addUser:String;
		public function addContactList(aliass:Array):void{
			if(aliass.length>0){
				var rst:URLRequest = new URLRequest(encodeURI(Predef.CHAOS_HOST+CONTACT_URL));
				var vars:URLVariables = new URLVariables();
				vars.uid = DBAuthenticate.getInstance().dbUID;
				vars.op = "a";
				vars.aliass = JSON.encode(aliass);
				rst.data = vars;
				rst.method = URLRequestMethod.POST;
				_addUser = aliass.join("|");
				remoteRst.sendRequest(rst,onAddContactList);
			}
		}
		
		//TODO:
		public function checkActivate(id:int):void{
			
		}
		
		public function invite(id:int,name:String,alias:String,url:String,headimg:String):void{
			var rst:URLRequest = new URLRequest(encodeURI(Predef.CHAOS_HOST+CONTACT_URL));
			var vars:URLVariables = new URLVariables();
			vars.uid = DBAuthenticate.getInstance().dbUID;
			vars.op = "i";
			vars.invitetedid = id;
			vars.name = name;
			vars.alias = alias;
			vars.url = url;
			vars.headimg = headimg;
			rst.data = vars;
			rst.method = URLRequestMethod.POST;
			remoteRst.sendRequest(rst,onInvite);
		}
		
		private function onInvite(rstStr:String):void{
			ChaosLogPanel.getInstance().addTempBasicInfo("添加邀请对象成功");
			onGetContactList(rstStr);
		}
		
		private function onAddContactList(rstStr:String):void{
			ChaosLogPanel.getInstance().addTempBasicInfo("添加"+_addUser+"为推荐对象成功");
			onGetContactList(rstStr);
		}
		
		public function deleteContactList(ids:Array):void{
			if(ids.length>0){
				var rst:URLRequest = new URLRequest(encodeURI(Predef.CHAOS_HOST+CONTACT_URL));
				var vars:URLVariables = new URLVariables();
				vars.uid = DBAuthenticate.getInstance().dbUID;
				vars.op = "d";
				vars.uids = ids.join("|");
				rst.data = vars;
				rst.method = URLRequestMethod.POST;
				remoteRst.sendRequest(rst,onDeleteContactList);
			}
		}
		
		private function onDeleteContactList(rstStr:String):void{
			ChaosLogPanel.getInstance().addTempBasicInfo("删除推荐对象成功");
			onGetContactList(rstStr);
		}
		
		public function getContactInfo(uid:int):UserInfo{
			for each(var info:UserInfo in _list){
				if(info.dbID == uid){
					return info;
				}
			}
			return null;
		}
		
		private function searchUser(q:String):void{
			if(isSendingRequest==false){
				var rst:URLRequest = new URLRequest();
				rst.url = SprintfUtil.sprintf("http://api.douban.com/people?q=%s&start-index=%d&max-results=%d",encodeURI(q),0,10);
				rst.method = URLRequestMethod.GET;
				isSendingRequest = true;
				op = SEARCH_USER_INFO;
				loader.load(rst);
			}
		}
		
		private function onLoadComplete(e:Event):void{
			var rst:String = (e.currentTarget as URLLoader).data as String;
			isSendingRequest = false;
			switch(op){
				case SEARCH_USER_INFO:
					var rstArr:Array = parseSearchUserRst(rst);
					if(rstArr!=null){
						dispatchEvent(new ContactEvent(ContactEvent.ADD_UNACTIVATE_USER,rstArr));
					}else{
						ChaosLogPanel.getInstance().addTempBasicInfo("你要添加的"+decodeURI(_addUser)+"，从豆瓣搜索不到这个用户");
						dispatchEvent(new ContactEvent(ContactEvent.ADD_ILLAGEL_USER,rst));
					}
					break;
				case SEARCH_MY_INFO:
					var myselfRst:Array =  parseSearchUserRst(rst);
					if(myselfRst!=null && myselfRst.length>=1){
						var info:UserInfo =myselfRst[0];
						dispatchEvent(new ContactEvent(ContactEvent.SEARCH_MY_SELF_INFO,info));
					}
					break;
				case SEARCH_DB_USER_INFO:
					onGetDBUserInfoRst(rst);
					break;
			}
		}
		
		private function onGetDBUserInfoRst(str:String):void{
			var obj:Object = JSON.decode(str);
			if(obj!=null){
				var userInfo:UserInfo = new UserInfo();
				userInfo.dbUID = obj.uid as String;
				userInfo.dbName = obj.screen_name as String;
				userInfo.dbURL = SprintfUtil.sprintf("http://www.douban.com/people/%d/",_searchUID);
				userInfo.imgUrl = obj.small_avatar as String;
				userInfo.location = obj.city as String;
				userInfo.signature = obj.description as String;
				dispatchEvent(new ContactEvent(ContactEvent.SEARCH_DB_USER_INFO,userInfo));
			}else{
				dispatchEvent(new ContactEvent(ContactEvent.SEARCH_DB_USER_INFO_FAILED,_searchUID));
			}
		}
		
		private function onChaosErr(e:ChaosErrorEvent):void{
			switch(e.errcode){
				case ChaosErrMsgConfig.ADD_NONE_EXIST_CONTACT_ITEMS:
					searchUser(_addUser);
					Logger.getInstance().logError(e.type,e.msg);
					ChaosLogPanel.getInstance().addTempBasicInfo(e.msg);
					break;
				case ChaosErrMsgConfig.ADD_USERS_WITH_SAME_NAME:
					handleSameNameUsers(e.content);
					break;
				default:
					dispatchEvent(new ContactEvent(ContactEvent.OTHER_ERR_HAPPEN));
					Logger.getInstance().logError(e.type,e.msg);
					ChaosLogPanel.getInstance().addTempBasicInfo(e.msg);
					break;
			}
		}
		
		private function handleSameNameUsers(content:String):void{
			var users:Array = JSON.decode(content) as Array;
			var userInfoList:Array = [];
			for each(var user:Object in users){
				var userInfo:UserInfo = new UserInfo();
				userInfo.dbUID = user.uidstr as String;
				userInfo.dbName = user.name as String;
				userInfo.dbID = user.uid as int;
				userInfo.dbURL = user.dburl as String;
				userInfo.imgUrl = user.headimg as String;
				userInfo.isActivate = user.isactivate as int;
				userInfoList.push(userInfo);
			}
			dispatchEvent(new ContactEvent(ContactEvent.ADD_IN_SAME_NAMES,userInfoList));
		}
		
		private function parseSearchUserRst(str:String):Array{
			var xml:XML = new XML(str);
			namespace openSearch = "http://a9.com/-/spec/opensearchrss/1.0/";
			use namespace openSearch;
			namespace db = "http://www.douban.com/xmlns/";
			use namespace db;
			namespace w3c = "http://www.w3.org/2005/Atom";
			use namespace w3c;
			trace("豆瓣搜索结果：",xml.openSearch::totalResults);
			var rstLenStr:String = xml.openSearch::totalResults;
			
			if(parseInt(rstLenStr)>0){
				var info:UserInfo;
				var rst:Array = [];
				for each(var entry:XML in xml.children()){
					if(entry.name().localName == "entry"){
						info = new UserInfo();
						info.dbUID = entry.db::uid;
						var idstr:String = entry.w3c::id;
						idstr = idstr.slice(idstr.lastIndexOf("/")+1,idstr.length); 
						info.dbID = parseInt(idstr);
						info.dbURL = "http://www.douban.com/people/"+info.dbID;
						info.dbName = entry.w3c::title;
						info.signature = entry.db::signature;
						info.location = entry.db::location;
						info.imgUrl = entry.w3c::link.(@rel=="icon").@href;
						rst.push(info);
					}
				}
				return rst;
			}else{
				return null;
			}
		}
		
		private var formatter:DateFormatter;
		private function parseContactList(rst:Array):void{
			_list = new ArrayCollection();
			for each(var userObj:Object in rst){
				var user:UserInfo = new UserInfo();
				user.dbName = userObj.name as String;
				user.dbID = userObj.uid as int;
				user.dbUID = userObj.uidstr as String;
				user.dbURL = userObj.dburl as String;
				user.imgUrl = userObj.headimg as String;
				user.isActivate = userObj.isactivate as int;
				if(formatter == null){
					formatter = new DateFormatter();
					formatter.formatString = "yyyy-mm-dd hh:mm:ss";
				}
				user.lastActivitTime = DateFormatter.parseDateString(userObj.activietime as String);
				user.color = Math.random() * 0xFFFFFF;
				this._list.addItem(user);
			}
			
		}
		
		private function onIOError(e:IOErrorEvent):void{
			isSendingRequest = false;
			Logger.getInstance().logError("ContactManager error happend");
		}
	}
}